import C_Game from "./C_Game";
import C_App from "./core/C_App";
import { C_NotificationConst } from "./core/C_NotificationConst";
import C_NodePool from "./core/utils/C_NodePool";
import C_SoundManager, { SoundName } from "./core/utils/C_SoundManager";
import C_Box from "./game/component/C_Box";
import C_Customs from "./game/component/C_Customs";
import C_Hole from "./game/component/C_Hole";
import C_Screw from "./game/component/C_Screw";
import C_SpBox from "./game/component/C_SpBox";
let _onTouchEnded = cc.Button.prototype._onTouchEnded;
cc.Button.prototype._onTouchEnded = function (event) {
    _onTouchEnded.call(this, event);
    // if (this.isNotPlayClickBtn) {
    //     return
    // }
    // if (this.isNotOpen) {
    //     App.SoundManager.playEffect("ban", false);
    // }
    // else {
    //     // App.SoundManager.playEffect("clickBtn");
    //     App.SoundManager.playEffect("点击音效")
    // }
}
const { ccclass, property } = cc._decorator;

/** 游戏主玩法 */
@ccclass
export default class C_GameScrew extends cc.Component {


    @property([cc.Prefab])
    customsList: cc.Prefab[] = [];

    @property(cc.Node)
    gameNode: cc.Node = null;

    @property(C_NodePool)
    screwPool: C_NodePool = null;

    @property(cc.Node)
    boxNode: cc.Node = null;

    @property(C_SpBox)
    tempBox: C_SpBox = null;

    @property(cc.ProgressBar)
    proBar: cc.ProgressBar = null;

    @property(cc.Label)
    proLab: cc.Label = null;

    @property(cc.Label)
    numLab: cc.Label = null;

    @property(cc.Label)
    titleLab: cc.Label = null;


    @property(cc.Prefab)
    exitPre: cc.Prefab = null;

    /** 关卡数据 */
    customsData: { [key: number]: number } = {};
    _total: number = 0;
    /** 工具箱子 */
    boxes: C_Box[] = [];



    curIndex = 0;
    start() {

    }

    protected onLoad(): void {

        this.boxNode.children.forEach(v => {
            this.boxes.push(v.getComponent(C_Box));
        })
    }


    _isInit: boolean = true;
    initGame(index: number) {
        C_SoundManager.instance.playBg(SoundName.Bg)
        this.curIndex = index;
        if (this._isInit) {
            cc.tween(this.node)
                .delay(0)
                .call(() => {
                    this.initCustoms();
                })
                .start();
            this._isInit = false;
        }
        else {
            this.initCustoms();
        }
    }

    _customs: C_Customs = null;
    /** 初始化关卡数据 */
    initCustoms() {
        this.gameNode.removeAllChildren();
        const len = this.customsList.length;
        const template = this.customsList[this.curIndex > len - 1 ? (this.curIndex % (len - 1) + 1) : this.curIndex];
        if (template) {
            const node = cc.instantiate(template);
            this.gameNode.addChild(node);
            const customs = this._customs = node.getComponent(C_Customs);
            customs.initCustoms();
            this.customsData = customs.getData();
            this._total = customs.getTotal();
            this._boxColors = customs.getColorsSort();
            this.initBox();
            this.tempBox.initBox(-1);
            C_App.NotificationCenter.addListener(C_NotificationConst.OPEN_SCREW, this.onOpenScrew, this, 10);
            C_App.NotificationCenter.addListener(C_NotificationConst.FULL_BOX, this.onFullBox, this);
            this.titleLab.string = `第${this.curIndex + 1}关`;
            this.proBar.progress = 0.1;
            this.proLab.string = `进度0%`;
        }
    }

    exitCustoms() {
        if (this._customs) {
            this._customs.exitCustoms();
            this._customs = null;
            C_SoundManager.instance.stopBg();
        }
    }

    _boxColors: number[]
    /** 初始化工具箱 */
    initBox(isAni?: boolean) {
        for (const box of this.boxes) {
            if ((!box.isActive && !box.isAni && box.getEmptyPos() == -1) || !isAni) {
                if (this._boxColors.length) {
                    const color = this._boxColors.shift();

                    box.initBox(color, isAni);
                    // return;
                }
                else {
                    box.hideBox();
                    // return;
                }
            }
        }
        if (isAni) {
            cc.tween(this.node)
                .delay(.5)
                .call(() => {
                    this.updateTempBox()
                })
                .start();
        }
        // console.log("wtf>>>", this.boxes);
    }

    checkPass() {
        for (let key in this.customsData) {
            if (this.customsData[key] > 0) {
                return false;
            }
        }
        return true;
    }

    checkFailed() {
        const isFull = this.tempBox.checkIsFull(true);
        return isFull;
    }

    checkHole() {
        for (const box of this.boxes) {
            const isFull = box.checkIsFull();
            if (!isFull) {
                return true;
            }

        }

        if (!this.tempBox.checkIsFull()) {
            return true;
        }
    }


    moveToTarget(hole: C_Hole, box: C_Box, index: number, pos) {
        const color = hole.color;
        const node = this.screwPool.pop();
        const screw = node.getComponent(C_Screw);
        screw.color = color;

        this.gameNode.addChild(node);
        const startPos = this.gameNode.convertToNodeSpaceAR(pos)
        node.position = startPos;
        const holePos = box.getHolePosByIndex(index);
        let targetPos = box.node.convertToWorldSpaceAR(holePos);
        targetPos = this.gameNode.convertToNodeSpaceAR(targetPos);
        box.occupyPos(index)
        node.angle = 0;
        // 计算距离
        const distance = startPos.sub(targetPos).mag(); // 使用向量减法后计算模长
        cc.tween(node)
            .to(.4, { scale: 1.5, angle: 360 })
            .call(() => {
                C_SoundManager.instance.playEffect(SoundName.Fly_Screw);
            })
            .to(distance / 2400, { position: targetPos })
            .to(.2, { scale: 1, angle: 0 })
            .call(() => {
                box.addScrew(index, color);
                this.screwPool.push(node);
                if (box instanceof C_SpBox)
                    this.updateTempBox();
            })
            .start()
    }

    /** 判断临时工具箱是否可以移到工具箱中 */
    updateTempBox() {
        this.boxes.forEach(v => {
            while (1) {
                if (!v.checkIsFull()) {
                    const data = this.tempBox.getHoleByColor(v.color);
                    if (data) {

                        const hole = data.hole;
                        const index = data.index;
                        const result = this.onOpenScrew(hole, hole.node.convertToWorldSpaceAR(hole.screwNode.position), true)
                        if (result) {
                            this.tempBox.removeScrew(index);
                        }
                        // this.moveToTarget(hole, v, v.getEmptyPos(), hole.node.convertToWorldSpaceAR(hole.screwFrame.node.position))

                    }
                    else {
                        break;
                    }
                }
                else {
                    break;
                }
            }
        })
    }

    onTouchOver() {
        this.node.addChild(cc.instantiate(this.exitPre));
    }

    onTouchGoto() {
        C_Game.instance.endTryGame();
    }

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    onFullBox(box: C_Box) {
        const color = box.color;
        if (color > -1)
            this.customsData[color] -= 3;
        let num = 0;
        for (let key in this.customsData) {
            const value = this.customsData[key];
            num += value
        }
        const pro = Math.ceil(num / this._total * 100);
        this.proBar.progress = Math.max(.1, 1 - num / this._total);
        this.proLab.string = `进度${100 - pro}%`;
        this.initBox(true);
        const isPass = this.checkPass();
        if (isPass) {
            C_App.NotificationCenter.removeListener(C_NotificationConst.OPEN_SCREW, this.onOpenScrew, this);
            C_App.NotificationCenter.removeListener(C_NotificationConst.FULL_BOX, this.onFullBox, this);
            C_Game.instance.onPassCustoms(this.curIndex);
        }

        const isFailed = this.checkFailed();
        if (isFailed) {


            C_App.NotificationCenter.removeListener(C_NotificationConst.OPEN_SCREW, this.onOpenScrew, this);
            C_App.NotificationCenter.removeListener(C_NotificationConst.FULL_BOX, this.onFullBox, this);

            this.boxes.forEach(v => {
                v.isActive = false;
            })
            this.tempBox.isActive = false;
            C_Game.instance.onFailedCustoms();
        }
        cc.tween(this.node)
            .delay(.1)
            .call(() => {
                this.updateTempBox()
            })
            .start();
    }

    onOpenScrew(hole: C_Hole, pos, isTempBox?: boolean) {
        // if (index !== undefined) {
        //     hole.removeScrew();
        //     this.moveToTarget(hole, this.tempBox, index, pos);

        //     return true;
        // }
        // else {
        const index = this.tempBox.getEmptyPos();
        if (index > -1 || isTempBox) {
            for (const box of this.boxes) {
                const index = box.getEmptyPos();
                if (box.checkColor(hole.color) && index > -1) {
                    hole.removeScrew();
                    this.moveToTarget(hole, box, index, pos);
                    return true;
                }
            }
        }

        if (index > -1 && !isTempBox) {
            hole.removeScrew();
            this.moveToTarget(hole, this.tempBox, index, pos);

            return true;
        }
        else {

        }
        // }
    }

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

}

